package loja.dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import loja.dao.exceptions.BuscaException;
import loja.dao.exceptions.ImpossivelAtualizarException;
import loja.dao.exceptions.ImpossivelCriarException;
import loja.dao.exceptions.ImpossivelDeletarException;
import loja.dominio.Produto;

/**
 *
 * @author Rodrigo
 */
public class ProdutoDao extends AbstractGenericDao<Produto> {

    public ProdutoDao() {
    }

    @Override
    public void criar(Produto produto) throws ImpossivelCriarException {
        String sql = "insert into produto (produto,preco,idmarca,idcategoria) values (?,?,?,?)";
        PreparedStatement stmt = null;

        try {
            iniciarTransacao();
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, produto.getDescricao());
            stmt.setDouble(2, produto.getPreco());
            stmt.setLong(3, produto.getMarca().getId());
            stmt.setLong(4, produto.getCategoria().getId());
            stmt.execute();
            comitarTransacao();
            JOptionPane.showMessageDialog(null, "Registro salvo com SUCESSO!!!");
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new ImpossivelCriarException("Não foi possível criar um novo produto.");
        } finally {
            closeStatement(stmt);
        }
    }

    @Override
    public void atualizar(Produto produto) throws ImpossivelAtualizarException {
        String sql = "update produto set idmarca=?, idcategoria=?, produto=?, preco=? where idproduto=?";
        PreparedStatement stmt = null;

        try {
            iniciarTransacao();
            stmt = getConexao().prepareStatement(sql);
            stmt.setLong(1, produto.getMarca().getId());
            stmt.setLong(2, produto.getCategoria().getId());
            stmt.setString(3, produto.getDescricao());
            stmt.setDouble(4, produto.getPreco());
            stmt.setLong(5, produto.getId());
            // Executa o código sql
            stmt.execute();
            comitarTransacao();
            JOptionPane.showMessageDialog(null, "Registro alterado com SUCESSO!!!");
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new ImpossivelAtualizarException("Não foi possível atualizar o produto.");
        } finally {
            closeStatement(stmt);
        }
    }

    @Override
    public void deletar(Produto produto) throws ImpossivelDeletarException {
        String sql = "delete from produto where idproduto=?";
        PreparedStatement stmt = null;

        try {
            iniciarTransacao();
            stmt = getConexao().prepareStatement(sql);
            stmt.setLong(1, produto.getId());
            stmt.execute();
            comitarTransacao();
            JOptionPane.showMessageDialog(null, "Registro excluido com SUCESSO!!!");
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new ImpossivelDeletarException("Não foi possível excluir o produto.");
        } finally {
            closeStatement(stmt);
        }
    }

    @Override
    public Produto buscar(Long id) throws BuscaException {
        String sql = "select * from produto where idproduto=?";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Produto produto = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            stmt.setLong(1, id);
            rs = stmt.executeQuery();
            while (rs.next()) {
                produto = construirProduto(rs);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível buscar o produto.");
        }
        return produto;
    }

    @Override
    public List<Produto> buscarTodos() throws BuscaException {
        String sql = "select * from produto";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Produto> produtos = null;
        Produto produto = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            rs = stmt.executeQuery();
            produtos = new ArrayList<Produto>();
            while (rs.next()) {
                produto = construirProduto(rs);
                produtos.add(produto);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProdutoDao.class.getName()).log(Level.SEVERE, null, ex);
            throw new BuscaException("Não foi possível buscar os produtos.");
        }
        return produtos;
    }

    @Override
    public long contar() throws BuscaException {
        String sql = "select count(*) from produto";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Long total = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            rs = stmt.executeQuery();
            while (rs.next()) {
                total = rs.getLong(1);
            }
        } catch (SQLException ex) {
            Logger.getLogger(VendaDao.class.getName()).log(Level.SEVERE, null, ex);
            throw new BuscaException("Não foi possível contar produtos.");
        }
        return total;
    }

    private Produto construirProduto(ResultSet rs) throws SQLException, BuscaException {
        Produto produto = new Produto();
        CategoriaDao dao = new CategoriaDao();
        MarcaDao marcaDao = new MarcaDao();
        produto.setId(rs.getLong("idproduto"));
        produto.setCategoria(dao.buscar(rs.getLong("idcategoria")));
        produto.setDescricao(rs.getString("produto"));
        produto.setMarca(marcaDao.buscar(rs.getLong("idmarca")));
        produto.setPreco(rs.getDouble("preco"));

        return produto;

    }

    public List<Produto> buscarPorDescricao(String descricao) throws BuscaException {
        String sql = "select * from produto where produto like ?";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Produto> produtos = null;
        Produto produto = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, "%" + descricao + "%");
            rs = stmt.executeQuery();
            produtos = new ArrayList<Produto>();
            while (rs.next()) {
                produto = construirProduto(rs);
                produtos.add(produto);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProdutoDao.class.getName()).log(Level.SEVERE, null, ex);
            throw new BuscaException("Não foi possível buscar as Descrição dos  produtos.");
        }
        return produtos;
    }
}
